home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / news / readers / skim-0.8 / skim-0 / skim-0.8.4 / PostArticle.c < prev    next >
C/C++ Source or Header  |  1996-02-18  |  7KB  |  255 lines

  1. /*
  2.  * NAME
  3.  *   PostArticle.c
  4.  * USAGE
  5.  *   Usage: PostArticle ArticleFile ...
  6.  * DESCRIPTION
  7.  *   Post one or more articles to USENET.
  8.  * COPYRIGHT
  9.  *   Skim - Off-line news reading package optimized for slow lines.
  10.  *   Copyright (C) 1996  Rene W.J. Pijlman
  11.  *
  12.  *   This program is free software; you can redistribute it and/or modify
  13.  *   it under the terms of the GNU General Public License as published by
  14.  *   the Free Software Foundation; either version 2 of the License, or
  15.  *   (at your option) any later version.
  16.  *
  17.  *   This program is distributed in the hope that it will be useful,
  18.  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  19.  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20.  *   GNU General Public License for more details.
  21.  *
  22.  *   You should have received a copy of the GNU General Public License
  23.  *   along with this program; if not, write to the Free Software
  24.  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  25.  * VERSION
  26.  *   Skim version 0.8.4.
  27.  */
  28.  
  29. #include <assert.h>
  30.  
  31. #include "Skim.h"
  32. #include "SkimUtils.h"
  33. #include "StandardIO.h"
  34. #include "NNTPStream.h"
  35. #include "Article.h"
  36. #include "VarBuf.h"
  37.  
  38. FILE_ID("$Header: /home/rene/sys/CVS_MasterSourceRepository/skim/PostArticle.c,v 1.6 1996/02/18 11:40:20 rene Exp $");
  39.  
  40.  
  41. /* Return a copy of an article in the format required by RFC 977. */
  42. static VarBuf FormatAsRequiredByRFC977( VarBuf ArticleVB )
  43. {
  44.     VarBuf New = VBCreate();
  45.     Boolean OnFirstPositionOfLine = True;
  46.     char * p;
  47.  
  48.     for ( p = VBAsString(ArticleVB); *p; p++ )
  49.     {
  50.     if ( OnFirstPositionOfLine && *p == '.' )
  51.     {
  52.         VBAppendString( New, ".." );
  53.     }
  54.     else if ( *p == '\n' )
  55.     {
  56.         VBAppendString( New, "\r\n" );
  57.     }
  58.     else
  59.     {
  60.         VBAppendCharacter( New, *p );
  61.     }
  62.  
  63.     OnFirstPositionOfLine = ( *p == '\n' );
  64.     }
  65.  
  66.     return New;
  67. }
  68.  
  69.  
  70. /* ArticleToPost is in UNIX text file representation. */
  71. static Boolean PostArticleToNewsServer(
  72.     StandardIO NewsServer, VarBuf ArticleToPost )
  73. {
  74.     Boolean Success = True;
  75.  
  76.     assert( NewsServer != NULL );
  77.     assert( SIOIsOpenForWrite(NewsServer) && SIOIsOpenForRead(NewsServer) );
  78.  
  79.     SIOInternetCommand( NewsServer, "post" );
  80.     Success = CheckStatusResponse( NewsServer, NULL, "340", NULL, 
  81.                                    DONT_TERMINATE_ON_ERROR );
  82.  
  83.     if ( Success )
  84.     {
  85.     VarBuf FormattedAsRequiredByRFC977 =
  86.         FormatAsRequiredByRFC977( ArticleToPost );
  87.  
  88.     SIOPrintf( NewsServer, "%V.\r\n", FormattedAsRequiredByRFC977 );
  89.  
  90.         Success = CheckStatusResponse( NewsServer, NULL, "240",
  91.                                    NULL, DONT_TERMINATE_ON_ERROR );
  92.  
  93.     VBDestroy( FormattedAsRequiredByRFC977 );
  94.     }
  95.  
  96.     return Success;
  97. }
  98.  
  99.  
  100. static void PrepareForPost( Article ArticleUnderConstruction )
  101. {
  102.     VarBuf Signature = NULL;
  103.     VarBuf X_NewsReader = NULL;
  104.     VarBuf From = NULL;
  105.     VarBuf Path = NULL;
  106.     VarBuf ReplyTo = NULL;
  107.     VarBuf Organization = NULL;
  108.  
  109.     ItemsFromEnvironment( &Signature, &X_NewsReader, &From, &ReplyTo,
  110.               &Path, &Organization );
  111.  
  112.     ArticlePrepareForPost( ArticleUnderConstruction, From, Path, ReplyTo,
  113.                Organization, X_NewsReader );
  114.  
  115.     VBDestroy( Signature );
  116.     VBDestroy( X_NewsReader );
  117.     VBDestroy( From );
  118.     VBDestroy( Path );
  119.     VBDestroy( ReplyTo );
  120.     VBDestroy( Organization );
  121. }
  122.  
  123.  
  124. /* VB to Article, prepare for post, Article to VB. */
  125. static Boolean PostArticleVB( 
  126.     VarBuf ArticleVB, StandardIO * NewsServer, VarBuf * ArticleAsPosted )
  127. {
  128.     Boolean Success = True;
  129.     Article ArticleUnderConstruction = ArticleCreate();
  130.     
  131.     assert( ArticleAsPosted != NULL && *ArticleAsPosted == NULL );
  132.  
  133.     ArticleSetVB( ArticleUnderConstruction, ArticleVB );
  134.     PrepareForPost( ArticleUnderConstruction );
  135.     if ( ArticleIsOKAndComplete( ArticleUnderConstruction ) )
  136.     {
  137.     *ArticleAsPosted = ArticleGetVB( ArticleUnderConstruction );
  138.  
  139.     if ( *NewsServer == NULL )
  140.     {
  141.         *NewsServer = NNTPStreamOpen();
  142.     }
  143.     assert( *NewsServer != NULL );
  144.  
  145.     if ( !PostArticleToNewsServer( *NewsServer, *ArticleAsPosted ) )
  146.     {
  147.         Success = False;
  148.     }
  149.     }
  150.     else
  151.     {
  152.     Success = False;
  153.     SIOPrintf( StandardError, "%V",
  154.         ArticleGetErrorMessages(ArticleUnderConstruction) );
  155.     }
  156.  
  157.     ArticleDestroy( ArticleUnderConstruction );
  158.  
  159.     assert ( !Success || *ArticleAsPosted != NULL );
  160.  
  161.     return Success;
  162. }
  163.  
  164.  
  165. /* File management. */
  166. static Boolean PostArticleFile(
  167.     const char * FileName, StandardIO * NewsServer )
  168. {
  169.     Boolean Success = True;
  170.     VarBuf FullPath = VBCreate();
  171.     StandardIO ArticleFile = SIOCreate();
  172.     VarBuf ArticleVB = VBCreate();
  173.     VarBuf FullPathPosted = VBCreate();
  174.     StandardIO CopyInPosted = SIOCreate();
  175.     VarBuf ArticleAsPosted = NULL;
  176.  
  177.     assert( FileName != NULL && strlen(FileName) > 0 );
  178.  
  179.     VBPrintf( FullPath, "%s/Post/%s", SkimDirectory(), FileName );
  180.     SIOFileOpen( ArticleFile, VBAsString(FullPath), OpenModeRead );
  181.     VBReadFile( ArticleVB, ArticleFile );
  182.     SIOFileClose( ArticleFile );
  183.  
  184.     Success = PostArticleVB( ArticleVB, NewsServer, &ArticleAsPosted );
  185.     if ( Success )
  186.     {
  187.         assert( VBSize(ArticleAsPosted) > 0 );
  188.  
  189.     VBPrintf( FullPathPosted, "%s/Posted/%s", SkimDirectory(), FileName );
  190.     SIOFileOpen( CopyInPosted, VBAsString(FullPathPosted), 
  191.                  OpenModeWriteDiscardOld );
  192.     VBWriteFile( ArticleAsPosted, CopyInPosted );
  193.     SIOFileClose( CopyInPosted );
  194.  
  195.     /* Posted OK, kept copy, so remove the article file now. */
  196.     SIORemove( VBAsString(FullPath) );
  197.     }
  198.  
  199.     VBDestroy( FullPath );
  200.     SIODestroy( ArticleFile );
  201.     VBDestroy( ArticleVB );
  202.     VBDestroy( FullPathPosted );
  203.     SIODestroy( CopyInPosted );
  204.     VBDestroy( ArticleAsPosted );
  205.  
  206.     return Success;
  207. }
  208.  
  209.  
  210. /* Loop over all filename arguments. */
  211. int main( int argc, char **argv )
  212. {
  213.     Boolean AllArticlesPosted = True;
  214.     StandardIO NewsServer = NULL;
  215.     int i;
  216.  
  217.     if ( argc < 1 )
  218.     {
  219.         SIOPrintf( StandardError, "%s\n",
  220.                            "Usage: PostArticle ArticleFile ..." );
  221.         exit( EXIT_FAILURE );
  222.     }
  223.  
  224.     for ( i = 1; i < argc; i++ )
  225.     {
  226.     if ( strlen(argv[i]) > 0 )
  227.     {
  228.         SIOPrintf( StandardOutput, "Posting article %s.\n", argv[i] );
  229.         SIOFlushBuffers( StandardOutput );
  230.  
  231.         if ( PostArticleFile( argv[i], &NewsServer ) )
  232.         {
  233.         SIOPrintf( StandardOutput,
  234.                "Article %s posted successfully.\n", argv[i] );
  235.         }
  236.         else
  237.         {
  238.         AllArticlesPosted = False;
  239.         SIOPrintf( StandardError, "Error: Article %s not posted.\n",
  240.                    argv[i] );
  241.         }
  242.     }
  243.     }
  244.  
  245.     if ( !AllArticlesPosted && argc > 2 )
  246.     {
  247.     SIOPrintf( StandardError,
  248.        "One or more articles were not posted successfully.\n" );
  249.     }
  250.  
  251.     NNTPStreamClose( NewsServer );
  252.  
  253.     return AllArticlesPosted ? EXIT_SUCCESS : EXIT_FAILURE;
  254. }
  255.